package com.decard.hbs.biz.util;

import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.app.Connection;
import ca.uhn.hl7v2.app.Initiator;
import ca.uhn.hl7v2.llp.MinLowerLayerProtocol;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.parser.DefaultXMLParser;
import ca.uhn.hl7v2.parser.PipeParser;
import ca.uhn.hl7v2.parser.XMLParser;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

public class Hl7Client{

    private static final Logger log = LoggerFactory.getLogger(Hl7Client.class);

    public static String sendAndReceive(String host,int port,String msg) throws Exception {
        log.info("=====================host = {},port = {},msg = {}",host,port,msg);
        Connection connection = null;
        HapiContext context = null;
        try {
            context = new DefaultHapiContext();
            MinLowerLayerProtocol mllp = new MinLowerLayerProtocol();
            mllp.setCharset("GBK");
            context.setLowerLayerProtocol(mllp);

            connection = context.newClient(host,port,false);
            PipeParser pipeParser = PipeParser.getInstanceWithNoValidation();
            Initiator initiator = connection.getInitiator();


            Message parse = pipeParser.parse(msg);
            Message message = initiator.sendAndReceive(parse);
            log.info("=====================message.encode() = {}",message.encode());
            XMLParser xmlParser = new DefaultXMLParser();
            Document document = xmlParser.encodeDocument(message);
            String xmlStr = XmlUtil.toStr(document);
            log.info("=====================xmlStr = {}",xmlStr);
            return xmlStr;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("hl7调用出现异常", e);
            throw e;
        }finally {
            if (connection != null) {
                connection.close();
            }
            if (context != null) {
                context.close();
            }
        }
    }

    public static String sendAndReceiveForClinicPayment(String host,int port,String msg) throws Exception {
        log.info("=====================host = {},port = {},msg = {}",host,port,msg);
        Connection connection = null;
        HapiContext context = null;
        try {
            context = new DefaultHapiContext();
            MinLowerLayerProtocol mllp = new MinLowerLayerProtocol();
            mllp.setCharset("GBK");
            context.setLowerLayerProtocol(mllp);

            connection = context.newClient(host,port,false);
            PipeParser pipeParser = PipeParser.getInstanceWithNoValidation();
            Initiator initiator = connection.getInitiator();


            Message parse = pipeParser.parse(msg);
            Message message = initiator.sendAndReceive(parse);
            log.info("=====================message.encode() = {}",message.encode());
            XMLParser xmlParser = new DefaultXMLParser();
            Document document = xmlParser.encodeDocument(message);
            String xmlStr = XmlUtil.toStr(document);
            log.info("=====================xmlStr = {}",xmlStr);
            //特殊处理
            JSONObject jsonObject = XML.toJSONObject(xmlStr);
            JSONObject rar_rar = jsonObject.getJSONObject("RAR_RAR");
            if(rar_rar.containsKey("ORC")){
                if(rar_rar.get("ORC") instanceof JSONObject){
                    JSONArray objects = new JSONArray();
                    objects.add(rar_rar.get("ORC"));
                    rar_rar.set("ORC", objects);
                }
                if(rar_rar.get("RXA") instanceof JSONObject){
                    JSONArray objects = new JSONArray();
                    objects.add(rar_rar.get("RXA"));
                    rar_rar.set("RXA", objects);
                }
                JSONArray RXAS = rar_rar.getJSONArray("RXA");
                JSONArray ORCS = rar_rar.getJSONArray("ORC");
                //分组
                JSONArray RXAGroup = new JSONArray();
                JSONArray RXAItem = new JSONArray();
                for (int i = 0; i < RXAS.size(); i++) {
                    if(i>0 && RXAS.getJSONObject(i).getInt("RXA.1") <= RXAS.getJSONObject(i-1).getInt("RXA.1")){
                        RXAGroup.add(RXAItem);
                        RXAItem = new JSONArray();
                    }
                    RXAItem.add(RXAS.getJSONObject(i));
                    if(i == RXAS.size()-1){
                        RXAGroup.add(RXAItem);
                    }
                }
                //赋值
                for (int i = 0; i < ORCS.size(); i++) {
                    JSONObject entries = new JSONObject();
                    entries.set("RXA", RXAGroup.getJSONArray(i));
                    ORCS.getJSONObject(i).set("RXADETAIL", entries);
                }
                jsonObject.remove("RXA");
                xmlStr = XML.toXml(jsonObject);
            }
            //特殊处理
            return xmlStr;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("hl7调用出现异常", e);
            throw e;
        }finally {
            if (connection != null) {
                connection.close();
            }
            if (context != null) {
                context.close();
            }
        }
    }

    public static void main(String[] args) throws Exception {
//        String msg = "MSH|^~\\&|JK160|1|HIS||20240619174114||QBP^Q21|09ee283c-25cd-4447-9d0e-e9a3e6aeattt|P|2.4|||AL|AL|CHN|UNICODE|||\r"
//                + "QPD|||440303201904070107^^^^IdentifyNO||汪锶骐||||||||\r";
//        String receive = sendAndReceive("10.10.252.163", 1600, msg);
//        log.info("receive = " + receive);

        //取号
        String msg = "MSH|^~\\&|HIS||ZZJ||20240709141755||RAR^RAR|37412784|P|2.4|||AL|AL|CHN\r"
                + "MSA|AA|4a8b2eb1-3ce4-11ef-ba61-ab467e466b39|成功|100|F\r"
                + "PID||0000095049\r"
                + "PV1||||||||||||||||||01|212603\r"
                + "NTE|||282.94|^Zfzje\r"
                + "NTE|||0.00|^Sbzje\r"
                + "ORC||17624835^5^212603^O|212603^900001332226|||||||000133^张苑|||0305^肾内科门诊|||||||282.94||||||1|440300||11^普通门诊\r"
                + "RXA|1|0.0324|||Y00000001850^白茅根^^-1|0.00|g^1000g/kg||||||0.00||||||||||||||||1|11\r"
                + "RXA|2|28.0000|||F00000018574^血浆凝血酶原时间测定(PT)-仪器法^^0|1.00|项||||||28.00||||||||||||||F00000092037|凝血四项|1|11\r"
                + "RXA|3|23.0000|||F00000018602^血浆纤维蛋白原测定-仪器法^^0|1.00|项||||||23.00||||||||||||||F00000092037|凝血四项|1|11\r"
                + "RXA|4|23.0000|||F00000018590^活化部分凝血活酶时间测定(APTT)-仪器法^^0|1.00|项||||||23.00||||||||||||||F00000092037|凝血四项|1|11\r"
                + "RXA|5|18.0000|||F00000018633^凝血酶时间测定(TT)-仪器法^^0|1.00|项||||||18.00||||||||||||||F00000092037|凝血四项|1|11\r"
                + "RXA|6|150.0000|||F00000017770^胎儿心脏彩色多普勒超声^^0|1.00|胎次||||||150.00||||||||||||||F00000095485|产检补充：Ⅲ级产科超声检查（20～24周）（三维）|1|11\r"
                + "RXA|7|40.0000|||F00000017764^脏器灰阶立体成象^^0|1.00|每个脏器||||||40.00||||||||||||||F00000095485|产检补充：Ⅲ级产科超声检查（20～24周）（三维）|1|11\r"
                + "RXA|8|0.9400|||Y00000002391^0.9%氯化钠注射液^^-1|1.00|支^10ml：0.09g*1支||||||0.94||||||||||||||||1|11\r";
//
//        String msg = "MSH|^~\\\\&|HIS||JK160||20240619174115||RSP^K21|611645478|P|2.4|||AL|AL|CHN\r"
//                + "MSA|AA|09ee283c-25cd-4447-9d0e-e9a3e6aeabf2|成功|100|F\r"
//                + "PID||0001457233|440303201904070107^^^^IdentifyNO||汪锶骐||20190407000000|F|||||^^^^^^^^13926598292|||||||||||||||||||||||||1^自费\r";
        PipeParser pipeParser = PipeParser.getInstanceWithNoValidation();
        Message parse = pipeParser.parse(msg);
        XMLParser xmlParser = new DefaultXMLParser();
        Document document = xmlParser.encodeDocument(parse);
        String xmlStr = XmlUtil.toStr(document);
        log.info("=====================xmlStr = {}",xmlStr);


        //特殊处理
        JSONObject jsonObject = XML.toJSONObject(xmlStr);
        JSONObject rar_rar = jsonObject.getJSONObject("RAR_RAR");
        if(rar_rar.containsKey("ORC")){
            if(rar_rar.get("ORC") instanceof JSONObject){
                JSONArray objects = new JSONArray();
                objects.add(rar_rar.get("ORC"));
                rar_rar.set("ORC", objects);
            }
            if(rar_rar.get("RXA") instanceof JSONObject){
                JSONArray objects = new JSONArray();
                objects.add(rar_rar.get("RXA"));
                rar_rar.set("RXA", objects);
            }
            JSONArray RXAS = rar_rar.getJSONArray("RXA");
            JSONArray ORCS = rar_rar.getJSONArray("ORC");
            //分组
            JSONArray RXAGroup = new JSONArray();
            JSONArray RXAItem = new JSONArray();
            for (int i = 0; i < RXAS.size(); i++) {
                if(i>0 && RXAS.getJSONObject(i).getInt("RXA.1") <= RXAS.getJSONObject(i-1).getInt("RXA.1")){
                    RXAGroup.add(RXAItem);
                    RXAItem = new JSONArray();
                }
                RXAItem.add(RXAS.getJSONObject(i));
                if(i == RXAS.size()-1){
                    RXAGroup.add(RXAItem);
                }
            }
            //赋值
            for (int i = 0; i < ORCS.size(); i++) {
                JSONObject entries = new JSONObject();
                entries.set("RXA", RXAGroup.getJSONArray(i));
                ORCS.getJSONObject(i).set("RXADETAIL", entries);
            }
            jsonObject.remove("RXA");
            xmlStr = XML.toXml(jsonObject);
        }
        //特殊处理
        System.out.println(xmlStr);


    }
}
